﻿using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;

namespace Pay.DTO
{
	/// <summary>
	/// 支付请求
	/// </summary>
	public class PayRequestDto : IValidatableObject
	{
		/// <summary>
		/// 支付类型
		/// </summary>
		[Required]
		[EnumDataType(typeof(PayCategoryEnum))]
        public PayCategoryEnum PayCategory { get; set; }

		/// <summary>
		/// 应用appId,
		/// </summary>
		[Required]
		public string AppId { get; set; }

		/// <summary>
		/// 支付渠道
		/// </summary>
		[Required]
		[EnumDataType(typeof(PaySourceEnum))]
		public PaySourceEnum PaySource { get; set; }

		/// <summary>
		/// 商户订单号
		/// </summary>
		[Required]
		[StringLength(32, MinimumLength = 6)]
		public string OutTradeNo { get; set; }

		/// <summary>
		/// 订单金额,元,精度0.01
		/// </summary>
		[Required]
		public decimal Amount { get; set; }

		/// <summary>
		/// 订单描述、商品描述
		/// </summary>
		[Required]
		[StringLength(127)]
		public string Description { get; set; }

		/// <summary>
		/// 支付回调URL
		/// </summary>
		[Required]
		[StringLength(256)]
		public string NotifyUrl { get; set; }

		/// <summary>
		/// 订单附加数据，一般支付成功后会回调此数据,数据不能太多
		/// </summary>
		[StringLength(128)]
		public string? Attach { get; set; }

		/// <summary>
		/// 支付授权码；刷码(商家扫码)支付时必填
		/// </summary>
		public string? AuthCode { get; set; }

		/// <summary>
		/// 终端IP；微信支付时必填，
		/// </summary>
		public string? SpBillCreateIp { get; set; }

		/// <summary>
		/// 对应openid；微信小程序、公众号支付时必填，
		/// </summary>
		public string? OpenId { get; set; }

		/// <summary>
		/// 是否指定服务商分账，可不填；微信支付时可用;Y->分账 N->不分账，默认N
		/// </summary>
		public string? ProfitSharing { get; set; }

		/// <summary>
		/// 业务产品码；支付宝app、网页支付时可填；
		/// APP支付：QUICK_MSECURITY_PAY ->无线快捷支付产品, CYCLE_PAY_AUTH ->周期扣款产品；
		/// PC网页支付：FAST_INSTANT_TRADE_PAY ->新快捷即时到账产品；
		/// 移动网页支付：QUICK_WAP_WAY ->无线快捷支付产品；
		/// 转账：TRANS_ACCOUNT_NO_PWD ->单笔无密转账到支付宝账户, STD_RED_PACKET ->收发现金红包
		/// </summary>
		public string? ProductCode { get; set; }

		/// <summary>
		/// 商家扫码场景；支付宝刷码(商家扫码)支付时可填；默认值为bar_code ;
		/// 枚举值： bar_code：当面付条码支付场景； security_code：当面付刷脸支付场景，对应的auth_code为fp开头的刷脸标识串；
		/// 周期扣款或代扣场景无需传入，协议号通过agreement_params参数传递；  支付宝预授权和新当面资金授权场景无需传入，授权订单号通过 auth_no字段传入。
		/// </summary>
		public string? Scene { get; set; }

		/// <summary>
		/// 支付宝网页支付时，同步回调URL；可空
		/// </summary>
		public string? ReturnUrl { get; set; }

		/// <summary>
		/// 请求基URL
		/// </summary>
		[JsonIgnore]
		public string? BaseUrl { get; set; }

		/// <summary>
		/// Validate
		/// </summary>
		public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
		{
			if (PaySource == PaySourceEnum.PassiveCode && string.IsNullOrWhiteSpace(AuthCode))
			{
				yield return new ValidationResult("商家扫码支付时，AuthCode授权码必填");
				yield break;
			}

			if (PayCategory == PayCategoryEnum.WechatPay && string.IsNullOrWhiteSpace(SpBillCreateIp))
			{
				yield return new ValidationResult("微信支付时，SpBillCreateIp终端IP必填");
				yield break;
			}

			if (PayCategory == PayCategoryEnum.WechatPay && (PaySource == PaySourceEnum.Miniprogram | PaySource == PaySourceEnum.Public)
				&& string.IsNullOrWhiteSpace(OpenId))
			{
				yield return new ValidationResult("微信小程序、公众号支付时，OpenId必填");
				yield break;
			}

			if (PayCategory == PayCategoryEnum.WechatPay && string.IsNullOrWhiteSpace(ProfitSharing))
				ProfitSharing = "N";

			if (PayCategory == PayCategoryEnum.AliPay && string.IsNullOrWhiteSpace(ProductCode))
			{
				switch (PaySource)
				{
					case PaySourceEnum.App:
						ProductCode = "QUICK_MSECURITY_PAY";
						break;
					case PaySourceEnum.PCWeb:
						ProductCode = "FAST_INSTANT_TRADE_PAY";
						break;
					case PaySourceEnum.MobileWeb:
						ProductCode = "TRANS_ACCOUNT_NO_PWD";
						break;
					default:
						break;
				}
			}

			if (PayCategory == PayCategoryEnum.AliPay && PaySource == PaySourceEnum.PassiveCode && string.IsNullOrWhiteSpace(Scene))
				Scene = "bar_code";
			if (string.IsNullOrWhiteSpace(Attach))
				Attach = string.Empty;
		}
	}
}